package main

import (
	error2 "awesomeProject/error"
	"awesomeProject/functional"
	"awesomeProject/person"
	"awesomeProject/tree"
	"fmt"
	"io/ioutil"
	"net/http"
)

func main() {
	functional.Do()
	error2.File_put_contents("a.txt")
}

/*
	利用别名来扩展已有的类型
	缺点：只能添加方法，不能添加变量
*/
type Queue []int

func (q *Queue) Push(v int) {
	*q = append(*q, v)
}

type BackNode tree.TreeNode

/*
	使用内嵌的方法实现近似继承
*/
type NewNode struct {
	*tree.TreeNode
}

/*
	重载（或者叫做shadow）
*/
func (node *NewNode) Print() {
	fmt.Printf("new print :%d", node.Value)
}
func main1() {
	var root tree.TreeNode
	root = tree.TreeNode{Value: 3, Left: &tree.TreeNode{}, Right: &tree.TreeNode{5, nil, nil}}
	root.Right.Left = new(tree.TreeNode)
	nodes := []tree.TreeNode{
		root,
		*root.Right,
		*root.Right.Left,
	}
	root.Value = 4
	fmt.Println(nodes[0].GetValue())
	//proot := &root
	fmt.Printf("%d ", root)
	/*
		看来是值传递
	*/
	root.Tranverse()
}

func wget() string {
	res, err := http.Get("https://baidu.com")
	if err != nil {
		panic(err)
	}
	//result, _ := httputil.DumpResponse(res, true)
	str, _ := ioutil.ReadAll(res.Body)
	res.Body.Close()
	return string(str)
}

type Person interface {
	Die(int) string
}

func main2() {
	stud := person.Student{}
	var stu Person = &stud
	var i interface{} = stud
	/*
		当使用指针参数时新的String()只会被指针变量调用
		当使用值参数时都可调用
	*/
	fmt.Println(stud, stu, i)

	fmt.Printf("直接打印类型%T \n", i)
	v, ok := i.(person.Student)
	if ok {
		/*
			只有经过断言后才可以作为student访问Age
		*/
		fmt.Printf("这是一个%d岁的学生", v.Age)
	} else {
		fmt.Println("这啥也不是")
	}
	fmt.Println(i)
	switch v := i.(type) {
	case int:
		fmt.Println("这是一个int")
	case person.Student:
		fmt.Println(v)
		fmt.Println("这是一个Student，他现在死给你看")
		v.Die(5)
	case *person.Student:
		fmt.Println("这是一个Student指针")

	default:
		fmt.Println("啥也不是")
	}
	//fmt.Println(stu.(*person.Student).Age)
	tea := new(person.Teacher)
	fmt.Println(tea.Die(5))
	/*
		golang中的接口是面向使用者的，不是面向struct的开发者的
		当初始化一个interface变量并储存一个子struct时
		该变量保存了两部分  一部分为对应struct的类型  另一部分为对应struct的内容或指针
		interface只能使用interface规定的func
		当需要作为对应struct使用时，要进行assertion
		assertion有两种 直接.()或switch
		golang中万物皆interface{}
	*/

}

/*
	接口的组合
*/
type Farmer interface {
	Farm()
}
type Worker interface {
	Work()
}
type FarmWorker interface {
	Farmer
	Worker
	Person
	Whoami() string
}
